package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"unicode"
	"unicode/utf8"
)

func main() {
	counts := make(map[rune]int)
	chartype := make(map[string]int)

	var utflen [utf8.UTFMax + 1]int //数组
	invalid := 0

	in := bufio.NewReader(os.Stdin)

	for {
		r, n, err := in.ReadRune() // returns rune, nbytes, error
		if err == io.EOF {
			break
		}
		if err != nil {
			fmt.Fprintf(os.Stderr, "charcount: %v\n", err)
		}
		if r == unicode.ReplacementChar && n == 1 { //无效字符，无效字符的长度是1
			invalid++
			continue
		}
		counts[r]++
		utflen[n]++

	}

	fmt.Printf("rune\tcount\n")

	for c, n := range counts {
		if unicode.IsLetter(c) {
			chartype["letter"] += n
		}
		if unicode.IsNumber(c) {
			chartype["number"] += n
		}
		if unicode.IsSymbol(c) {
			chartype["symbol"] += n
		} else {
			chartype["other"] += n
		}
		fmt.Printf("%q\t%d\n", c, n)
	}

	for k, v := range chartype {
		fmt.Printf("%q\t%d\n", k, v)
	}

	fmt.Print("\nlen\tcount\n")

	for i, n := range utflen {
		if i > 0 {
			fmt.Printf("%d\t%d\n", i, n)
		}
	}

	if invalid > 0 {
		fmt.Printf("\n%d invalid UTF-8 characters\n", invalid)
	}

}
